#include <iostream>
using namespace std;
int main() {
  /* */
    // eg1.校门外的树
    // 声明树数组，记录对应位置树坑的状态
    int trees[10001] = {0};
    // 声明马路长度 L 和区域数 M
    int L, M;
    // 声明区域的起始位置 start 和结束位置 end
    int start, end;
    // 声明计数器 counter 记录剩余的树
    int counter = 0;
    cin >> L >> M;
    // 初始化树数组
    for (int i = 0; i <= L; i++) {
      // 往坑里种树
      trees[i] = 1;
    }
    // 移树：外层循环
    for (int i = 0; i < M; i++) {
      cin >> start >> end;
      // 在指定区域移树：内层循环
      for (int j = start; j <= end; j++) {
        trees[j] = 0;
      }
    }
    // 数剩余的树
    for (int i = 0; i <= L; i++) {
      // 坑里有树
      if (trees[i] == 1) {
        counter++;
      }
    }
    cout << counter << endl;


  /*
  // eg2.校门外的树（增强版）
  // 树数组
  int trees[10001] = {0};
  // 马路长度 l 和操作数 n
  int l, n;
  // 身份码 who 开始索引 start 结束索引 end
  int who, start, end;
  // 种树量 plant，砍树量 cut
  int plant, cut = 0;
  // 输入
  cin >> l >> n;
  plant = l;
  // 初始化树数组
  for (int i = 0; i < l; i++) {
    trees[i] = 1;
  }
  // 操作（种树或砍树）：外层循环
  for (int i = 0; i < n; i++) {
    cin >> who >> start >> end;
    // 树操作：内层循环
    for (int j = start; j <= end; j++) {
      // 树操作：光头强砍树，熊大种树
      if (who == 0) {
        trees[j] = 0;
        cut++;
      }else{
        trees[j] = 1;
        plant++;
      }
    }
  }
  // 输出：剩余树量 = 种树量 - 砍树量
  cout << plant - cut << endl;
  */
  /*
  // eg3.最大值和最小值的差
  // 待求序列
  int a[10001];
  // 序列长度
  int n;
  cin >> n;
  // 初始化序列
  for (int i = 0; i < n; i++) {
    cin >> a[i];
  }
  // 获取最大值和最小值
  int max = a[0], min = a[0];
  for (int i = 0; i < n; i++) {
    if (a[i] > max) {
      max = a[i];
    }
    if (a[i] < min) {
      min = a[i];
    }
  }
  // 输出最大值和最小值的差
  cout << max - min << endl;
  */
  /*
  // eg4.铺地毯
  // 地毯信息：横坐标 a 纵坐标 b 宽度 w 高度 h
  int a[10001], b[10001], w[10001], h[10001];
  // 地毯数
  int n;
  cin >> n;
  // 初始化地毯信息
  for (int i = 0; i < n; i++) {
    cin >> a[i] >> b[i] >> w[i] >> h[i];
  }
  // 目标位置 x y
  int x, y;
  cin >> x >> y;
  // 声明边界：上下左右
  int top, bottom, left, right;
  // 遍历地毯信息：从 n 开始倒着求解，因为题目要求最上层地毯编号
  for (int i = n; i >= 1; i++) {
    // 获取边界值
    left = a[i];
    right = a[i] + w[i];
    bottom = b[i];
    top = b[i] + h[i];
    // 判断目标位置是否在地毯内
    if (x >= left && x <= right && y >= bottom && y <= top) {
        cout << i << endl;
        return 0;
    }
  }
  cout << -1 << endl;
  return 0;
  */
  /*
  // eg5.彩票摇奖
  // 购买的彩票数 n 中奖彩票 win 中奖情况 counter
  // counter[i] 一至六等奖：1~6 特等奖：0
  int n, win[8], counter[8];
  cin >> n;
  // 初始化中奖号码
  for (int i = 0; i < 7; i++) {
    win[i] = i;
  }
  // 一张一张兑奖：彩票号码对 num 中奖等级 level
  int num, level;
  for (int i = 1; i <= n; i++) {
    level = 0;
    // 兑奖
    for (int j = 0; j < 7; j++){
        // 输入彩票号码对
        cin >> num;
        if(num == win[j]){
            level++;
        }
    }
    // 中奖等级和索引号是负相关，因为 0 代表 特等奖，所以 7 - level
    counter[7 - level]++;
  }
  // 输出中奖情况
  for (int i = 6; i >= 0; i--) {
    cout << counter[i] << " ";
  }
  return 0;
  */
  /*
  // eg6.整数去重
  // 序列长度 n 序列 nums 序列顶部索引 top 待存入的数 x
  int n, x, nums[20001], top=0;
  cin >> n;
  for (int i = 0; i < n; i++) {
    cin >> x;
    // 是否有相同的数
    bool flag = false;
    for(int j = 0;j<top;j++){
        if(nums[j] == x){
            flag = true;
            break;
        }
    }
    // x 不存在则存入 flag = false
     if(!flag){
        nums[top] = x;
        top++;
    }
  }
  for (int i = 0; i < top; i++) {
    cout << nums[i] << " ";
  }
  return 0;
  */
}
